// --- BEGIN COPYRIGHT BLOCK ---
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// (C) 2007 Red Hat, Inc.
// All rights reserved.
// --- END COPYRIGHT BLOCK ---
package com.netscape.admin.certsrv;

import java.awt.Cursor;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.ResourceBundle;

import javax.swing.Icon;
import javax.swing.JFrame;

import com.netscape.admin.certsrv.config.install.InstallWizard;
import com.netscape.admin.certsrv.config.install.InstallWizardInfo;
import com.netscape.admin.certsrv.task.CMSConfigCert;
import com.netscape.admin.certsrv.task.CMSRemove;
import com.netscape.admin.certsrv.task.CMSRestart;
import com.netscape.admin.certsrv.task.CMSStart;
import com.netscape.admin.certsrv.task.CMSStartDaemon;
import com.netscape.admin.certsrv.task.CMSStatus;
import com.netscape.admin.certsrv.task.CMSStop;
import com.netscape.admin.certsrv.wizard.IWizardDone;
import com.netscape.admin.certsrv.wizard.WizardWidget;
import com.netscape.certsrv.common.ConfigConstants;
import com.netscape.certsrv.common.OpDef;
import com.netscape.certsrv.common.TaskId;
import com.netscape.management.client.Framework;
import com.netscape.management.client.IMenuInfo;
import com.netscape.management.client.IMenuItem;
import com.netscape.management.client.IPage;
import com.netscape.management.client.IResourceObject;
import com.netscape.management.client.IStatusItem;
import com.netscape.management.client.MenuItemSeparator;
import com.netscape.management.client.MenuItemText;
import com.netscape.management.client.ResourcePage;
import com.netscape.management.client.StatusItemSecureMode;
import com.netscape.management.client.console.ConsoleInfo;
import com.netscape.management.client.topology.AbstractServerObject;
import com.netscape.management.client.topology.IRemovableServerObject;
import com.netscape.management.client.util.Debug;
import com.netscape.management.client.util.LDAPUtil;
import com.netscape.management.client.util.RemoteImage;
import com.netscape.management.client.util.UtilConsoleGlobals;

import netscape.ldap.LDAPAttribute;
import netscape.ldap.LDAPConnection;
import netscape.ldap.LDAPDN;
import netscape.ldap.LDAPEntry;
import netscape.ldap.LDAPException;
import netscape.ldap.LDAPModification;
import netscape.ldap.LDAPModificationSet;
import netscape.ldap.LDAPSearchResults;

/**
 * Netscape Certificate Server 4.0 configuration entry point. The
 * directory server needs to contain the name of this class in order
 * for the topology view to load this class.
 *
 * @author Jack Pan-Chen
 * @author Thomas Kwan
 * @version $Revision$, $Date$
 * @date 01/12/97
 * @deprecated The PKI console will be removed once there are CLI equivalents of desired console features.
 */
@Deprecated(since = "10.14.0", forRemoval = true)
public class CMSAdmin extends AbstractServerObject
        implements IWizardDone, IRemovableServerObject, IMenuInfo {
    private static final long serialVersionUID = 1L;

    /*==========================================================
     * variables
     *==========================================================*/
    private static final String PREFIX = "CMSADMIN";
    private static final String START = "start";
    private static final String STOP = "stop";
    private static final String CONFIGURE = "configure";
    //    private static final String START_DAEMON_CGI = "Tasks/Operation/StartDaemon";

    private ConsoleInfo mConsoleInfo; // global information
    private CMSServerInfo mServerInfo; // server-specific information
    private ConsoleInfo mServerInstanceInfo;
    private CMSUIFramework mFramework; // parent frame
    //private CMSInfoPanel mInfoPanel;        // information panel
    private RemoteImage mIconImage = null; // server icon
    private String mServerID, mServerVersion, mInstallationDate, mServerRoot;
    private String mHost = null; // server name
    private int mPort = 0; // server port
    private int mServerStatus = STATUS_UNKNOWN;
    private JFrame mActiveFrame;

    protected ResourceBundle mResource; //resource boundle

    /*==========================================================
     * constructors
     *==========================================================*/
    public CMSAdmin() {
        //Debug.setTrace(true);
        if (mActiveFrame == null)
            mActiveFrame = UtilConsoleGlobals.getActivatedFrame();
        mResource = ResourceBundle.getBundle(CMSAdminResources.class.getName());
        // STATUS_UPDATE_INTERVAL = 1500000;
    }

    /*==========================================================
     * public methods
     *==========================================================*/

    public int getServerLastKnownStatus() {
        return mServerStatus;
    }

    /**
     * Initialize the page with global information.
     *
     * @param info global information.
     */
    @Override
    public void initialize(ConsoleInfo info) {
        mConsoleInfo = info;
        mIconImage = CMSAdminUtil.getImage(CMSAdminResources.IMAGE_CERTICON_SMALL);
        getInfo(info.getCurrentDN());
        //getServerStatus();
        if (info.getCurrentDN() == null) {
            Debug.println("initialized CMSAdmin (Standalone mode)");
        } else {
            super.initialize(info);
        }
        Debug.println("initialized CMSAdmin for " + mConsoleInfo.getCurrentDN());
    }

    /**
     * overwrite the base class to add admin port number
     * Not sure we want to do this.
     *
     * protected Vector initializeNodeDataVector(String dataKeys[]) {
     * Vector v = super.initializeNodeDataVector(dataKeys);
     * if ( mServerInfo != null ) {
     * int port = mServerInfo.getPort();
     * if ( port > 0 ) {
     * String label = mResource.getString(PREFIX+"_ADMINPORT_LABEL");
     * v.addElement(new NodeData("nsServerPort",
     * label,
     * Integer.toString(port)));
     * }
     * }
     * return v;
     * }
     */

    /**
     * return the server instance name instead for now
     *
     * @return return the server name
     *
     */
    @Override
    public String getName() {
        return ("Certificate Server (" + mServerID + ")");
    }

    /**
     * Return the information panel. - Admin take over this already
     *
     * @return information panel
     *
     *         public Component getCustomPanel() {
     *         if(mInfoPanel == null)
     *         mInfoPanel = new CMSInfoPanel( (IServerObject)this,
     *         mHost,
     *         mPort,
     *         mServerVersion,
     *         mInstallationDate,
     *         mAdminURL);
     *         return mInfoPanel;
     *         }
     */

    /**
     * Return connection info for a server instance.
     *
     * @return Connection info for a server instance.
     */
    public CMSServerInfo getServerInfo() {
        return mServerInfo;
    }

    public ConsoleInfo getServerInstanceInfo() {
        mServerInstanceInfo = (ConsoleInfo) mConsoleInfo.clone();
        return mServerInstanceInfo;
    }

    /**
     * Returns the global console info.
     *
     * @return Global console info reference.
     **/
    public ConsoleInfo getConsoleInfo() {
        return mConsoleInfo;
    }

    /**
     * This function is called when the certificate server is deselected
     * on the topology view.
     */
    @Override
    public void unselect(IPage viewInstance) {
        //      Debug.println( "DSAdmin unselect" );
        super.unselect(viewInstance);
        fireRemoveMenuItems(viewInstance, this);
    }

    /**
     * This function is called when the directory server is selected
     * on the topology view.
     */
    @Override
    public void select(IPage viewInstance) {
        /*
        if (_removed)
            return;
        */

        HourGlass hglass = new HourGlass(mActiveFrame);
        super.select(viewInstance); // sets _viewInstance used
                                    // by getViewInstance()
        Debug.println("CMSAdmin.select(): viewInstance =" +
                getViewInstance());
        fireAddMenuItems(viewInstance, this);
        if (mPort == 0) {
            fireDisableMenuItem(viewInstance, START);
            fireDisableMenuItem(viewInstance, STOP);
            fireEnableMenuItem(viewInstance, CONFIGURE);
        } else if (getServerStatus() == STATUS_STARTED) {
            fireDisableMenuItem(viewInstance, START);
            fireEnableMenuItem(viewInstance, STOP);
            fireDisableMenuItem(viewInstance, CONFIGURE);
        } else {
            fireEnableMenuItem(viewInstance, START);
            fireDisableMenuItem(viewInstance, STOP);
            fireDisableMenuItem(viewInstance, CONFIGURE);
        }
        if (hglass != null) {
            hglass.setNonWaitCursor();
            hglass = null;
        }
    }

    /**
     * Returns supported menu categories
     */
    @Override
    public String[] getMenuCategoryIDs() {
        return new String[] {
                ResourcePage.MENU_CONTEXT,
                ResourcePage.MENU_OBJECT
        };
    }

    /**
     * Add menu items for this page.
     *
     * @param category Which menu
     */
    @Override
    public IMenuItem[] getMenuItems(String category) {
        /* Same for both CONTEXT and OBJECT menus */
        return new IMenuItem[] {
                new MenuItemText(CONFIGURE,
                        CMSAdminResources.MENU_CONFIGURE_SERVER,
                        CMSAdminResources.MENU_CONFIGURE_SERVER_DESC),
                new MenuItemText(START,
                        CMSAdminResources.MENU_START_SERVER,
                        CMSAdminResources.MENU_START_SERVER_DESC),

                new MenuItemText(STOP,
                        CMSAdminResources.MENU_STOP_SERVER,
                        CMSAdminResources.MENU_STOP_SERVER_DESC),
                new MenuItemSeparator() };
    }

    /**
     * Notification that a menu item has been selected.
     */
    @Override
    public void actionMenuSelected(IPage viewInstance, IMenuItem item) {
        if (item.getID().equals(START)) {
            getServerInstanceInfo();
            /* Fire off the Start task */
            CMSStart task = new CMSStart();
            mConsoleInfo.put(CMSStart.START_TASK_CGI, mServerID);
            mConsoleInfo.put("serverRoot", mServerRoot);
            mConsoleInfo.put("servid", mServerID);
            task.initialize(mConsoleInfo);
            //task.setConsoleInfo( info );
            boolean status = task.run(null);
            if (status) {
                getServerStatus();
                enableStartStop(viewInstance);
            }
        } else if (item.getID().equals(STOP)) {
            CMSStop task = new CMSStop();
            getServerInstanceInfo();
            mConsoleInfo.put(CMSStop.STOP_TASK_CGI, mServerID);
            mConsoleInfo.put("servid", mServerID);
            mConsoleInfo.put("serverRoot", mServerRoot);
            task.initialize(mConsoleInfo);
            boolean status = task.run(null);
            if (status) {
                getServerStatus();
                enableStartStop(viewInstance);
            }
        } else if (item.getID().equals(CONFIGURE)) {
            startupInstallationWizard(viewInstance);
        }
    }

    public void updateMenu(IPage viewInstance) {
        getInfo(getConsoleInfo().getCurrentDN());
        if (mPort != 0) {
            fireDisableMenuItem(viewInstance, CONFIGURE);
            getServerStatus();
            enableStartStop(viewInstance);
        }
    }

    /**
     * Enable/Disable start/stop action menu.
     */
    private void enableStartStop(IPage viewInstance) {
        if (mServerStatus == STATUS_STOPPED) {
            fireEnableMenuItem(viewInstance, START);
            fireDisableMenuItem(viewInstance, STOP);
        } else if (mServerStatus == STATUS_STARTED) {
            fireEnableMenuItem(viewInstance, STOP);
            fireDisableMenuItem(viewInstance, START);
        }
    }

    /**
     * Set the title bar in the following format:
     * <p>
     *
     * <pre>
     *      [server information] - [server type] - [nickname]
     * </pre>
     *
     * Administrator id is shown at lower status bar
     */
    public void updateTitle() {
        /*
        mAuthid.setState(mResource.getString("CMSADMIN_USER_LABEL")+
            " = "+mServerInfo.getUserId()+"  ");
        mFramework.getFramework().changeStatusItemState(mAuthid);
        */
        String id = mServerID;
        int i = id.indexOf('-');
        if ((i > 0) && (i < (id.length() - 1)))
            id = id.substring(i + 1);
        mFramework.getFramework().setTitle(mServerInfo.getHost() + " - "
                + mResource.getString(CMSAdminResources.CERT_SERVER_NAME) +
                " - " + id);
    }

    private Hashtable<String, Object> createWizardInfo() {
        Hashtable<String, Object> data = new Hashtable<>();
        /* This does nothing
        data.put(ConfigConstants.TASKID,TaskId.TASK_LIST_PREVIOUS_STAGES);
        data.put(ConfigConstants.OPTYPE, OpDef.OP_READ);
        data.put(ConfigConstants.PR_CERT_INSTANCE_NAME, mServerID);
        data.put(ConfigConstants.PR_SERVER_ROOT, mServerRoot);
        */

        // moved from WIIntroPage.java
        data.put(ConfigConstants.TASKID, TaskId.TASK_GET_DEFAULT_INFO);
        data.put(ConfigConstants.OPTYPE, OpDef.OP_READ);
        data.put(ConfigConstants.PR_CERT_INSTANCE_NAME,
                mConsoleInfo.get(ConfigConstants.PR_CERT_INSTANCE_NAME));
        // #344791 - help server to make up the hostname
        data.put(ConfigConstants.PR_HOST,
                mConsoleInfo.get(ConfigConstants.PR_HOST));
        data.put(ConfigConstants.PR_SERVER_ROOT,
                mConsoleInfo.get(ConfigConstants.PR_SERVER_ROOT));
        return data;
    }

    /**
     * This is called when the installwizard is done.
     */
    @Override
    public void notify(WizardWidget w) {
        Debug.println("Configuration Completed");
        for (int i = 0; i < 10; i++) { // try to detect 10 times
            Debug.println("Check Status #" + i);
            if (getServerStatus() == STATUS_STARTED) {
                return;
            }
            try {
                Thread.sleep(2000); // 2 seconds
            } catch (Exception e) {
            }
        }
    }

    /**
     * Start up the installation wizard
     */
    public void startupInstallationWizard(IPage viewInstance) {
        Hashtable<String, Object> data = new Hashtable<>();
        CMSStartDaemon daemon = new CMSStartDaemon();
        mConsoleInfo.put("servid", mServerID);
        mConsoleInfo.put(CMSStartDaemon.START_DAEMON_CGI, mServerID);
        mConsoleInfo.put(CMSConfigCert.CONFIG_CERT_CGI, mServerID);
        daemon.initialize(mConsoleInfo);
        data.put(ConfigConstants.PR_CERT_INSTANCE_NAME, mServerID);
        Debug.println("about to run Daemon");
        boolean success = daemon.runDaemon(data);
        Debug.println("run daemon success = " + success);
        data.clear();
        data = null;
        boolean isInfoReady = false;

        if (success) {
            InstallWizardInfo wizardInfo = new InstallWizardInfo(mConsoleInfo);
            wizardInfo.setAdminFrame(mActiveFrame);
            Debug.println("CMSAdmin: creating new configCertCgi");
            CMSConfigCert configCertCgi = new CMSConfigCert();
            configCertCgi.initialize(wizardInfo);
            Debug.println("CMSAdmin: back from creating new configCertCgi");
            data = createWizardInfo();
            isInfoReady = configCertCgi.configCert(data);
            Debug.println("CMSAdmin: isInfoReady = " + isInfoReady);

            if (isInfoReady) {
                JFrame frame = new JFrame();
                Cursor cursor = new Cursor(Cursor.HAND_CURSOR);
                frame.setCursor(cursor);
                frame.invalidate();
                frame.validate();
                frame.repaint(1);
                // XXX - checking status is too slow, dont do it now.
                // InstallWizard wizard = new InstallWizard(
                //  mConsoleInfo.getFrame(), wizardInfo, this);
                InstallWizard wizard = new InstallWizard(mActiveFrame,
                        wizardInfo, null);
                wizardInfo.setAdminFrame(mActiveFrame);
                wizardInfo.put("viewInstance", viewInstance);
                wizardInfo.put("CMSAdmin", this);
                new Thread(wizard).start();
            }
        }
        data.clear();
        data = null;
        mServerStatus = STATUS_UNKNOWN;
    }

    /**
     * This function is called when the server is double clicked on
     * the topology view. Auth dialog is displayed to get user dn and pwd.
     */
    public boolean run(IPage viewInstance) {

        Debug.println("The user double click the icon " + getConsoleInfo().getCurrentDN());
        Debug.println("View instance in the run method -> " + viewInstance);

        if (getConsoleInfo().getCurrentDN() == null) {
            mServerID = (String) mConsoleInfo.get("cmsServerInstance");
        }

        mConsoleInfo.put(CMSRestart.RESTART_TASK_CGI, mServerID);
        mConsoleInfo.put(CMSStart.START_TASK_CGI, mServerID);
        mConsoleInfo.put(CMSStop.STOP_TASK_CGI, mServerID);
        mConsoleInfo.put("CMSAdmin", this);
        if (mPort == 0) {
            getInfo(getConsoleInfo().getCurrentDN());
            if (mPort == 0) {
                startupInstallationWizard(viewInstance);
                return false;
            }
        }

        if (getConsoleInfo().getCurrentDN() == null) {
            mHost = (String) mConsoleInfo.get("cmsHost");
            mPort = Integer.parseInt((String) mConsoleInfo.get("cmsPort"));
        } else {
            try {
                LDAPConnection ldc = mConsoleInfo.getLDAPConnection();
                if (ldc == null) {
                    Debug.println("No connection ready in ConsoelInfo");
                    ldc = new LDAPConnection();
                    ldc.connect(mConsoleInfo.getHost(), mConsoleInfo.getPort(),
                            mConsoleInfo.getAuthenticationDN(),
                            mConsoleInfo.getAuthenticationPassword());
                }
                //Debug.println( "Fetching " + sBase + " from " +
                //               mConsoleInfo.getHost() + ":" + mConsoleInfo.getPort() );
                LDAPEntry entry = ldc.read(mConsoleInfo.getCurrentDN());
                //Debug.println( "Got " + entry );

                try {
                    String port = getAttrVal(entry, "nsserverport");

                    if (port == null)
                        return false;
                    int portnum = Integer.parseInt(port);
                    if (portnum != mPort)
                        mPort = portnum;
                } catch (Exception e) {
                    CMSAdminUtil.showErrorDialog(mConsoleInfo.getFrame(), mResource,
                            e.toString(), CMSAdminUtil.ERROR_MESSAGE);
                    return false;
                }
            } catch (LDAPException ex) {
                CMSAdminUtil.showErrorDialog(mConsoleInfo.getFrame(), mResource,
                        ex.toString(), CMSAdminUtil.ERROR_MESSAGE);
            }
        }

        try {
            // server off
            if (getServerStatus() != STATUS_STARTED) {
                CMSAdminUtil.showMessageDialog(mConsoleInfo.getFrame(), mResource, PREFIX,
                        "SERVEROFF", CMSAdminUtil.ERROR_MESSAGE);
                return false;
            }

            /*
            mServerInfo = new CMSServerInfo(mHost, mPort, d.getUsername(),
                d.getPassword(),
                mServerID, mInstallationDate, mServerVersion, mServerRoot);
            */
            String path = (String) mConsoleInfo.get("cmsPath");
            mServerInfo = new CMSServerInfo(mHost, mPort, "", "",
                    mServerID, mInstallationDate, mServerVersion, mServerRoot, path);

            String authType = mServerInfo.getAuthType();

            // server is alive, do authenticate if the server asks for
            // password-based authentication
            if (authType.equals("pwd")) {
                CMSPassword d = new CMSPassword(mActiveFrame);
                d.setVisible(true);
                if (d.isCancel())
                    return false;
                mServerInfo = new CMSServerInfo(mHost, mPort, d.getUsername(),
                        d.getPassword(),
                        mServerID, mInstallationDate, mServerVersion, mServerRoot, path);
                mServerInfo.authenticate();
            }
            mConsoleInfo.put("serverInfo", mServerInfo);
        } catch (EAdminException ex) {
            CMSAdminUtil.showErrorDialog(mConsoleInfo.getFrame(), mResource,
                    ex.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
            System.exit(0); // exit if authentication fails
            return false;
        }

        //LOAD UI FRAMEWORK
        try {
            mFramework = new CMSUIFramework(mConsoleInfo, mServerInfo);
        } catch (EAdminException e) {
            CMSAdminUtil.showErrorDialog(mConsoleInfo.getFrame(), mResource,
                    e.getMessage(), CMSAdminUtil.ERROR_MESSAGE);
            return false;
        }

        //show secure status
        StatusItemSecureMode statusSecureMode = new StatusItemSecureMode(Framework.STATUS_SECURE_MODE);
        statusSecureMode.setSecureMode(true);
        mFramework.getFramework().addStatusItem(statusSecureMode, IStatusItem.LEFTFIRST);
        statusSecureMode.setToolTipText(mServerInfo.getHost() + ":" + mServerInfo.getPort());

        //show login status
        updateTitle();
        return true;
    }

    /**
     * Run the object
     *
     * @param viewInstance CMSPageFeeder object
     * @param selectionList List of selected objects
     */
    @Override
    public boolean run(IPage viewInstance, IResourceObject selectionList[]) {
        return run(viewInstance);
    }

    /**
     * perform the specified action. The command string is specified either
     * from the content menu or the menu bar.
     *
     * @param command Command String
     */
    public void performAction(String command) {

    }

    /**
     * Return the server icon.
     *
     * @return The Directory Server icon.
     */
    @Override
    public Icon getIcon() {
        return mIconImage;
    }

    public int getStatus() {
        return mServerStatus;
    }

    /**
     * Return the current status of the server (running or not).
     *
     * @return The Certificate Server status.
     */
    @Override
    public int getServerStatus() {
        Debug.println("Check server status");
        if (getConsoleInfo().getCurrentDN() == null) {
            return STATUS_STARTED;
        }
        if (mPort == 0) {
            mServerStatus = STATUS_UNKNOWN;
            return STATUS_UNKNOWN;
        }
        try {
            getServerInstanceInfo();
            CMSStatus task = new CMSStatus();
            mConsoleInfo.put(CMSStatus.STATUS_TASK_CGI, mServerID);
            mConsoleInfo.put("serverRoot", mServerRoot);
            mConsoleInfo.put("servid", mServerID);
            task.initialize(mConsoleInfo);
            //task.setConsoleInfo( info );
            boolean status = task.run(null);
            if (status) {
                mServerStatus = STATUS_STARTED;
                return STATUS_STARTED;
            }
            mServerStatus = STATUS_STOPPED;
            return STATUS_STOPPED;
        } catch (Exception e) {
            String bob = e.toString();
            Debug.println(bob);
            if (Debug.isEnabled())
                e.printStackTrace();
            return STATUS_UNKNOWN;
        }
    }

    /**
     * Return the current status of the server (running or not)
     * by pinging the agent HTTPS port.
     *
     * @return The Certificate Server status.
     */
    public boolean getStatusFromAgentPort() {

        if (mPort == 0) {
            getInfo(getConsoleInfo().getCurrentDN());
            if (mPort == 0) {
                //Debug.println("CMSAdmin: getServerStatus --> "+mServerStatus);
                return false;
            }
        }

        //check if ssl port is functional
        try {
            if ((mServerInfo == null) || (mServerInfo.getPort() == 0)) {
                String path = (String) mConsoleInfo.get("cmsPath");
                mServerInfo = new CMSServerInfo(mHost, mPort, "", "",
                        mServerID, mInstallationDate, mServerVersion, mServerRoot, path);
            }

            mServerInfo.ping();

        } catch (EAdminException e) {
            Debug.println("CMSAdmin: getServerStatus() -" + e.toString());
            if (e.getMessageString().equals(CMSAdminResources.SERVER_NORESPONSE) ||
                    e.getMessageString().equals(CMSAdminResources.SERVER_UNREACHABLE) ||
                    e.getMessageString().equals(CMSAdminResources.IOEXCEPTION) ||
                    e.getMessageString().equals(CMSAdminResources.UNKNOWNEXCEPTION) ||
                    e.getMessageString().equals(CMSAdminResources.UNKNOWNHOST)) {
                //                mServerStatus = STATUS_STOPPED;
                return false;
            }
            Debug.println("CMSAdmin: getServerStatus() -UNKNOWN");
            //            mServerStatus = STATUS_UNKNOWN;
            return false;
        }

        Debug.println("CMSAdmin: getServerStatus() -OK");
        //        mServerStatus = STATUS_STARTED;
        return true;
    }

    /**
     * The concrete class implementing this method will clone its
     * configuration from the reference server. This supports using the
     * GET method for cloning the server.
     *
     * @param referenceDN - DN of server to clone from.
     */
    @Override
    public void cloneFrom(String referenceDN) {
        //XXX TBD
    }

    /**
     * Implements the IRemovableServerObject interface.
     *
     * @return true if the server was successfully removed, false otherwise
     */

    @Override
    public boolean removeServer() {
        Debug.println("--------------  removeServer() ==== --------------------");

        Debug.println("getting console obj");
        getServerInstanceInfo();
        Debug.println("constuctor for remove");
        /* Fire off the Remove task */
        CMSRemove task = new CMSRemove();
        mConsoleInfo.put(CMSRemove.REMOVE_TASK_CGI, mServerID);
        mConsoleInfo.put("serverRoot", mServerRoot);
        mConsoleInfo.put("servid", mServerID);
        Debug.println("initalizing remove");
        task.initialize(mConsoleInfo);
        //task.setConsoleInfo( info );
        Debug.println("about to run remove rask");
        boolean status = task.run(null);
        Debug.println("remove run");
        Debug.println("Remove server status: " + status);
        String instance = (String) mConsoleInfo.get("ServerInstance");
        if (null == instance) {
            instance = "";
        }

        if (true == status) { /* successfully called remove cgi */
            Debug.println("removing topology for the server");
            LDAPConnection ldc = mConsoleInfo.getLDAPConnection();
            Debug.println("got the ldap connection");
            String[] attrs = { "*", "numsubordinates" };
            String sieDN = mConsoleInfo.getCurrentDN();
            Debug.println("removeServer:sieDN:" + sieDN);

            LDAPEntry sieEntry = null;
            try {
                sieEntry = ldc.read(sieDN, attrs);
                Debug.println("read a ldap entry");
            } catch (Exception ex) {
                Debug.println("removeServer <" + sieDN + "> " + ex);

                /*
                  args[1] = ex.toString();
                  DSUtil.showErrorDialog(_info.getFrame(), "removeinstance",
                  args);
                  _removed = false; // remove failed
                  */
                return false;
            }
            if (sieEntry != null) {
                try {
                    Debug.println("Calling delete_sieTree");
                    status = delete_sieTree(sieEntry);
                } catch (Exception ex) {
                    Debug.println("removeServer:Unable to delete the " +
                            "tree");
                    /*
                    args[1] = ex.toString();
                    DSUtil.showErrorDialog(_info.getFrame(), "removesie",
                    args);
                    _removed = false; // remove failed
                    */
                    return false;
                }
                // Now we need to remove the reference of this server
                Debug.println("calling remove_serverinstance");
                status = remove_serverInstance(sieDN);
            }
            /*
            if ( status	 == false) {
            args[1] = "";
            DSUtil.showErrorDialog(_info.getFrame(), "removesie",
            args);
            } else {
            DSUtil.showInformationDialog(_info.getFrame(), "121",
            (String)null) ;
            }

            */
        }
        //        CMSAdminUtil.showMessageDialog(mConsoleInfo.getFrame(), mResource, PREFIX,
        //                    "NOTIMPLEMENTED", CMSAdminUtil.ERROR_MESSAGE);
        return status;
    }

    private boolean delete_sieTree(LDAPEntry entry)
            throws LDAPException {

        LDAPConnection ldc = mConsoleInfo.getLDAPConnection();

        String dn = entry.getDN();
        if (entryHasChildren(entry)) {
            LDAPSearchResults search_results = null;
            String[] attrs = { "numsubordinates" };
            search_results = ldc.search(dn,
                    LDAPConnection.SCOPE_ONE,
                    "(objectClass=*)", attrs, false);

            while (search_results.hasMoreElements()) {
                /* Get the next child */
                LDAPEntry child_entry = search_results.next();
                delete_sieTree(child_entry);

            }
        }
        ldc.delete(dn);
        return true;
    }

    static boolean entryHasChildren(LDAPEntry entry) {
        boolean hasChildren = false;
        LDAPAttribute attr = entry.getAttribute(
                "numsubordinates");
        if (attr != null) {
            Enumeration<String> e = attr.getStringValues();
            if (e.hasMoreElements()) {
                String s = e.nextElement();
                int count = Integer.parseInt(s);
                if (count > 0) {
                    hasChildren = true;
                }
            }
        }
        return hasChildren;
    }

    private boolean remove_serverInstance(String sieDN) {

        LDAPSearchResults search_results = null;
        String baseDN = (String) mConsoleInfo.get("BaseDN");
        LDAPConnection ldc = mConsoleInfo.getLDAPConnection();
        String[] attrs = { "*", "uniquemember" };
        String filter = "(&(objectclass=groupOfUniquenames)(uniquemember=" +
                sieDN + "))";

        try {
            search_results = ldc.search(baseDN, LDAPConnection.SCOPE_SUB,
                    filter, attrs, false);
        } catch (LDAPException e) {
            Debug.println("Failed to search - " + e.toString());
            return false;
        }
        LDAPEntry entry = null;
        while (search_results.hasMoreElements()) {
            // need to remove the reference to the sieDN from
            // this entry.

            try {
                entry = search_results.next();
            } catch (LDAPException e) {
                throw new RuntimeException(e);
            }
            String eDN = entry.getDN();
            // Now we need to modify the entry to delete the
            // reference to the serevr.
            remove_intstanceFromEntry(ldc, eDN, sieDN);
        }
        return true;
    }

    private boolean remove_intstanceFromEntry(LDAPConnection ldc,
            String eDN, String sieDN) {

        LDAPModificationSet mods = new LDAPModificationSet();
        LDAPAttribute attUmember = new LDAPAttribute("uniquemember", sieDN);
        Debug.println("DSAdmin:remove_intstanceFromEntry: Modifying entry:" +
                eDN);
        mods.add(LDAPModification.DELETE, attUmember);
        try {
            ldc.modify(eDN, mods);
        } catch (LDAPException e) {
            Debug.println("Modifying " + eDN + ", " + e);
            return false;
        }
        return true;
    }

    /*==========================================================
     * private methods
     *==========================================================*/

    /**
     * Extract a single string
     *
     * @param entry A Directory entry
     * @param name Name of attribute to fetch
     * @return A concatenated string
     */
    private String getAttrVal(LDAPEntry entry, String name) {
        LDAPAttribute findAttr = entry.getAttribute(name, LDAPUtil.getLDAPAttributeLocale());
        if (findAttr != null) {
            return LDAPUtil.flatting(findAttr);
        }
        /*
        Debug.println( "Attribute " + name + " not found in " +
            entry.getDN() );
        */
        return null;
    }

    /**
     * get the attribute information to display in the information panel
     *
     * @param sDN DN for the entry.
     */
    private void getInfo(String sDN) {
        //String sBase = "cn=configuration, " + sDN;
        if (sDN == null) {
            mHost = (String) mConsoleInfo.get("cmsHost");
            mPort = Integer.parseInt((String) mConsoleInfo.get("cmsPort"));
        } else {
            String sBase = sDN;
            try {
                LDAPConnection ldc = mConsoleInfo.getLDAPConnection();
                if (ldc == null) {
                    Debug.println("No connection ready in ConsoelInfo");
                    ldc = new LDAPConnection();
                    ldc.connect(mConsoleInfo.getHost(), mConsoleInfo.getPort(),
                            mConsoleInfo.getAuthenticationDN(),
                            mConsoleInfo.getAuthenticationPassword());
                }
                //Debug.println( "Fetching " + sBase + " from " +
                //               mConsoleInfo.getHost() + ":" + mConsoleInfo.getPort() );
                LDAPEntry entry = ldc.read(sBase);
                //Debug.println( "Got " + entry );

                mHost = getAttrVal(entry, "serverHostName");
                try {
                    String port = getAttrVal(entry, "nsserverport");
                    if (port == null)
                        mPort = 0;
                    else
                        mPort = Integer.parseInt(port);
                } catch (Exception e) {
                    mPort = 0;
                }

                // get the attribute information for display purposes
                mServerVersion = getAttrVal(entry, "serverVersionNumber");
                mInstallationDate = getAttrVal(entry, "installationTimeStamp");
                mServerID = getAttrVal(entry, "nsserverid");
                mServerRoot = getAttrVal(entry, "serverroot");
                Debug.println("CMSAdmin::PR_HOST = " + mHost);
                mConsoleInfo.put(ConfigConstants.PR_HOST, mHost);
                mConsoleInfo.put(ConfigConstants.PR_SERVER_ROOT, mServerRoot);
                mConsoleInfo.put(ConfigConstants.PR_CERT_INSTANCE_NAME, mServerID);
            } catch (Exception e) {
                Debug.println("Fetching " + sBase + " from " +
                        mConsoleInfo.getHost() + ":" + mConsoleInfo.getPort() +
                        ", " + e);
            }

            mConsoleInfo.getAdminURL();

            /* Extract the username part of the admin authentication DN */
            String[] rdns = LDAPDN.explodeDN(mConsoleInfo.getAuthenticationDN(),
                    true);
            String s = rdns[0].trim();
            mConsoleInfo.put("AdminUsername", s);
            //getServerStatus();
        }
    }

    /**
     * Note: it would be better if this method were declared in the superclass,
     * but having it here is better than nothing, since I need access to it
     * for getServerStatus() . . .
     */
    private IPage getViewInstance() {
        return _viewInstance;
    }

    @Override
    public boolean isCloningEnabled() {
        return false;
    }

    @Override
    public boolean isMigrationEnabled() {
        return false;
    }
}
